
#include <klib.h>

#include <kmath.h>
#include <video.h>

int pows_of_ten[] = {1000000000, 100000000, 10000000, 1000000,
		     100000, 10000, 1000, 100, 10, 1};

int strlen(char *str){

  int i = 0;
  for (;; i++){
    if (str[i] == 0) return i;
  }

}

char _char_data[36] = {'0', '1', '2', '3', '4', '5', 
		       '6', '7', '8', '9', 'a', 'b', 
		       'c', 'd', 'e', 'f', 'g', 'h', 
		       'i', 'j', 'k', 'l', 'm', 'n', 
		       'o', 'p', 'q', 'r', 's', 't', 
		       'u', 'v', 'w', 'x', 'y', 'z'};

char _digit_to_char(unsigned int digit){

  if (digit >= (10 + 26)) return 0;

  return _char_data[digit];

}

void itos(int x, char *dest, int len){

  int i = 0;

  char buf[13];         // Ten for digits, 1 for a sign, and 1 for 0 = 13 bytes

  if (len == 0) return;
  if (len == 1) {
     buf[0] = 0;
  }

  if (x == 0){
    dest[0] = '0';
    dest[1] = 0;
    return;
  }

  if (x < 0) {
    buf[0] = '-';
    i++;
    x *= -1;
  }

  int p;
  for (p = 0; p < 10; p++){
    if (x >= pows_of_ten[i]){
      int digit = x / pows_of_ten[p];
      digit %= 10;
      digit += '0';
      buf[i++] = digit;
    } else {
      buf[i++] = '0';
    }
  }

  /* Pad the rest of the buffer with 0s. */
  while ((i + 1) < 13){
    buf[i++] = 0;
  }

  /* Trim leading zeros and copy the rest into the specified dest. */
  i = 0;
  p = 0;
  if (buf[0] == '-'){
    dest[0] = '-';
    i++;
    p++;
  }
  char found = 0;
  for ( ; i < 13; i++){
    if ((p + 1) >= len){
      dest[p] = '0';      /* We have used our dest capacity */
      return;
    }
    if (buf[i] != '0'){
      found = 1;
    }
    if (found){
      dest[p++] = buf[i];
    }
  }

  while ((p + 1) < len){
    dest[p++] = 0;
  }

}

void itox(unsigned int num, char *buf, int len){

  if (len <= 1) return;

  if ( num == 0){
    buf[0] = '0';
    buf[1] = 0;
    return;
  }

  char digits[8];

  int i = 0;
  for ( ; i < (len - 1); i++){
    if (i == 8) {
      break;
    }

    unsigned int cur_dig = num >> ((7 - i) * 4);
    unsigned int mask = 0xf; // Mask out all but the least significant 4 bits

    cur_dig &= mask;
    buf[i] = _digit_to_char(cur_dig);

  }

  buf[len-1] = 0;

}

void itobs(unsigned int num, char *dest){

  int i = 31;
  for ( ; i >= 0; i--){
    unsigned int mask = 1 << i;
    if (num & mask) {
      dest[31 - i] = '1';
    } else {
      dest[31 - i] = '0';
    }
  }
  dest[32] = 0;

}

int atoi(char *str, int *dest){

  int len = strlen(str);
  int i = 0;

  int val = 0;
  *dest = 0;

  for ( ; i < len; i++){
    int add, cur_ch;
    cur_ch = str[i] - '0';
    if (cur_ch < 0 || cur_ch > 9) return 0;
    add = pow(10, i);
  }

}

void memz(char *begin, int offset){

  int i = 0;
  for ( ; i < offset; i++){
    begin[i] = 0;
  }

}
